import { drizzle } from "drizzle-orm/mysql2";
import type { MySql2Database } from "drizzle-orm/mysql2";
import mysql from "mysql2/promise";

let managers: {
  [name: string]: {
    pool: mysql.Pool;
    db: MySql2Database;
  };
} = {};

/**
 * 连接配置
 */
type ConnectOption = {
  /**
   * 连接地址
   */
  urls: (string | { name: string; url: string | object })[];
  /** 是否记录日志 */
  logger?: boolean;
};

function parseMysqlUrl(urlinfo: string | object) {
  if (typeof urlinfo === "object") {
    return urlinfo;
  }
  const urlObj = new URL(urlinfo);
  return {
    host: urlObj.hostname,
    user: urlObj.username,
    password: urlObj.password,
    port: Number(urlObj.port || "3306"),
    database: urlObj.pathname.slice(1),
  };
}

/**
 * 连接数据库
 * @param option 连接配置
 * @example
 * connect({ logger: false, urls: ['mysql://x:x@127.0.0.1/x'] })
 */
export function connect(option: ConnectOption) {
  if (Array.isArray(option.urls)) {
    for (let i = 0, len = option.urls.length; i < len; i++) {
      const connectItem = option.urls[i];
      let name, cfg;
      if (typeof connectItem === "string") {
        cfg = parseMysqlUrl(connectItem);
        name = i === 0 ? "default" : `${i}`;
      } else {
        name = connectItem.name;
        cfg = parseMysqlUrl(connectItem.url);
      }
      const pool = mysql.createPool(cfg);
      managers[name] = {
        pool,
        db: drizzle(pool, { logger: option.logger }),
      };
    }
  }
}

/**
 * 获取访问数据库
 */
export function db(name = "default") {
  if (name in managers) {
    return managers[name].db;
  }
  throw new Error(`db ${name} not found`);
}

/**
 * 断开某个连接
 * @param name 连接名称, 默认: default
 */
export function close(name = "default") {
  if (name in managers) {
    managers[name].pool.end().then();
    managers[name] = undefined as any;
  }
}

/**
 * 断开所有连接
 */
export function closeAll() {
  for (const name in managers) {
    managers[name].pool.end().then();
  }
  managers = undefined as any;
}
